/**
 * 
 */
package org.robot;

import java.util.List;

import org.game.constant.SessionConstent;
import org.game.netty.oldcoder.other.EncryptionAndDecryptionUtil;
import org.game.netty.oldcoder.other.IChannelConstants;
import org.game.netty.oldcoder.other.HuanjieMessageFactory;
import org.game.netty.oldcoder.other.ProtocolConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sojoys.artifact.factory.message.IMessage;
import com.sojoys.artifact.factory.session.ISession;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.Attribute;

/**
 * 自定义密文解码器，负责解码，然后调用{@link HuanjieMessageFactory#create(Object, Object)}构建消息对象
 * 
 * @author wk.dai
 */
public class EchoDecoder extends ByteToMessageDecoder {
	private Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 获得解密钥密
	 * @param ctx
	 * @return
	 */
	private int[] getDecryptionKeys(ChannelHandlerContext ctx) {
		Channel channel = ctx.channel();
		// 取得session
		Attribute<ISession> attach = channel.attr(IChannelConstants.SESSION);
		ISession session = null;
		if((session = attach.get())==null){
			// 解密密钥
			Attribute<int[]> decryptionKeysAttribute = channel.attr(IChannelConstants.DECRYPTION_KEYS_ATTRIBUTE_KEY);
			int[] decryptionKeys = null;
			if((decryptionKeys=decryptionKeysAttribute.get())==null){
				// 设置默认解密密钥
				decryptionKeys = EncryptionAndDecryptionUtil.getDefaultCustomDecryptionKeys();
				decryptionKeysAttribute.set(decryptionKeys);
			}
			return decryptionKeys;
		}
		return session.getAttr(SessionConstent.DECRYPTION_KEYS);
	}
	
	
	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in,List<Object> out) throws Exception {
		if (in.readableBytes() < 6){
			return;
        }
		// 将当前的readerIndex备份到markReaderIndex中
		in.markReaderIndex();
		
		// 取得解密钥密
		int[] decryptKey = getDecryptionKeys(ctx);
		
		int flag = 0;
		int length = 0;
		
		byte[] validateData = new byte[6];
		in.readBytes(validateData);
		
		int[] copyDecryptKeys = new int[decryptKey.length];
		System.arraycopy(decryptKey, 0, copyDecryptKeys, 0, copyDecryptKeys.length);
		// 包头解密操作
		validateData = EncryptionAndDecryptionUtil.decryptCustom(validateData,copyDecryptKeys);
		// 包头BUF
		ByteBuf validateBuf = Unpooled.wrappedBuffer(validateData);
		// 取得分包标识
		flag = validateBuf.readShort();
		// 取得包长
		length = validateBuf.readInt();
		
		// 如果分包标识不同
		if (flag != ProtocolConstants.FLAG) {
			// 跳过全部内容
			in.skipBytes(in.readableBytes());
			ctx.close();
			return ;
		}

			
		// 如果能读内容不足4个字节
		if (in.readableBytes() < ProtocolConstants.HEAD_WITHOUT_FLAG_AND_LENGTH_SIZE) {
			// 重置读取标识在开始位置
			in.resetReaderIndex();
			return;
		}
		
		// 做兼容最大允许接受65535字节
		// length = length & 0x00FFFF;
		// 如果包长为0 跳过全部 视为非法包
		if (length <= 0) {
			in.skipBytes(in.readableBytes());
			ctx.close();
			return ;
		}
		
		@SuppressWarnings("unused")
		int bodyLength = length - ProtocolConstants.DEFAULT_HEADER_SIZE;
		int fixLength = length - ProtocolConstants.FLAG_AND_LENGTH_DATA_SIZE;
		
		// 是否读取完一个完整包内容
		if (fixLength > in.readableBytes()) {
			in.resetReaderIndex();
			return ;
		}

		// 消息体整体进行解密操作
		in.resetReaderIndex();
		
		//in.nioBuffer()返回的ByteBuffer是从当前读索引开始的拷贝
		EncryptionAndDecryptionUtil.decryptCustom(in.nioBuffer(),0, length, decryptKey);
		
		IMessage message = EchoMessageFactory.getDefault().create(ctx, in);
		if(message==null){
			return;
		}
		out.add(message);
	}
}
